<template>
  <div class="m-auto-scroll-table">
    <div class="header">
      <div 
        v-for="(col, index) in columns"
        :key="index"
        class="header-cell"
        :style="{
          textAlign: col.headerAlign ? col.headerAlign : (col.align ? col.align : 'auto'),
          width: col.width ? (String(col.width).indexOf('px') > -1 ? col.width : col.width + 'px') : 'auto',
          minWidth: col.width ? (String(col.minWidth).indexOf('px') > -1 ? col.minWidth : col.minWidth + 'px') : 'auto',
        }"
      >
        {{ col.title }}
      </div>
    </div>
    <div class="body" ref="body" @mouseenter="stopScroll" @mouseleave="startScroll">
      <div 
        v-for="(row, rowIndex) in data"
        :key="rowIndex"
        class="row"
      >
        <div
          v-for="(col, colIndex) in columns"
          :key="colIndex"
          class="cell"
          :style="{
            textAlign: col.align ? col.align : 'auto',
            width: col.width ? (String(col.width).indexOf('px') > -1 ? col.width : col.width + 'px') : 'auto',
            minWidth: col.width ? (String(col.minWidth).indexOf('px') > -1 ? col.minWidth : col.minWidth + 'px') : 'auto',
          }"
        >
          {{ col.formatter ? col.formatter({ cellValue: row[col.property], row }) : row[col.property] }}
        </div>
      </div>
      <div class="row finish" v-if="longger">没有更多数据</div>
    </div>
    <div v-if="props.loading" class="loading m-auto-scroll-table__box">
      <dv-loading>Loading...</dv-loading>
    </div>
    <div v-if="(props.data.length === 0 || props.config?.data?.length === 0) && !props.loading" class="no-data m-auto-scroll-table__box">
      <div>查无数据</div>
    </div>
  </div>
</template>

<script setup>
import { ref, onMounted, onUnmounted, watch, nextTick } from 'vue'

const props = defineProps({
  columns: {
    type: Array,
    required: true
  },
  data: {
    type: Array,
    required: true
  },
  speed: {
    type: Number,
    default: 80
  },
  loading: {
    type: Boolean
  }
})

// 变量
const body = ref(null)
let timer = null
const START_DUR_TIME = 10 // n个speed
let startDur = START_DUR_TIME // 当前到第几个speed
const END_DUR_TIME = 15 // 逗留n个speed
let endDur = END_DUR_TIME
const longger = ref(false)


// 监听 data 变化，实时更新视图
watch(
  () => props.data,
  (n, o) => {
    nextTick(() => {
      if (body.value) {
        body.value.scrollTop = 0
        caculateLongger()
        if (n.length > 0 && longger.value) {
          startScroll()
        } else {
          stopScroll()
        }
      }
    })
  },
  {
    immediate: true,
    deep: true
  }
)
watch(
  () => props.loading,
  (n, o) => {
    if (n) {
      stopScroll()
    }
  }
)


// 计算高度是否超长出现滚动条
function caculateLongger() {
  if (body.value) {
    const height = body.value.scrollHeight
    const clientHeight = body.value.clientHeight
    if (height > clientHeight) {
      longger.value = true
    } else {
      longger.value = false
    }
  }
}


// 开始滚动
const startScroll = () => {
  stopScroll()
  if (body.value) {
    caculateLongger()
    timer = setInterval(() => {
      const height = body.value.scrollHeight
      if (startDur <= START_DUR_TIME && startDur > 0) {
        // 滚动前-等待
        startDur--
      } else if (body.value.scrollTop + body.value.clientHeight >= height) {
        if (endDur <= END_DUR_TIME) {
          endDur--
          if (endDur < 0) {
            body.value.scrollTop = 0
            endDur = END_DUR_TIME
            startDur = START_DUR_TIME
          }
        }
      } else {
        body.value.scrollTop += 1
      }
    }, props.speed)
  }
}

// 暂停滚动
const stopScroll = () => {
  if (timer) {
    clearInterval(timer)
  }
}


// 生命周期
onMounted(() => {
  startScroll()
})

onUnmounted(() => {
  if (timer) {
    clearInterval(timer)
  }
})
</script>

<style lang="less" scoped>
@fontColor: #FFF;
@headerBGC: #222D75; // 标题
@oddRowBGC: #070750; // 奇数
@evenRowBGC: rgb(2, 24, 67); // 偶数

.m-auto-scroll-table {
  width: 100%;
  height: 100%;
  overflow: hidden;
  color: @fontColor;
  font-size: 16px;
  box-sizing: border-box;
  position: relative;
  .header {
    background-color: @headerBGC;
    .header-cell {
      // flex: 1;
      display: inline-block;
      line-height: 36px;
      padding: 0 5px;
      font-weight: bold;
    }
  }
  
  
  .body {
    height: calc(100% - 35px);
    overflow: hidden;
    .row {
      background-color: @evenRowBGC;
      min-height: 40px;
      &:hover {
        opacity: 0.8;
        cursor: pointer;
      }
      &:nth-child(2n-1) {
        background-color: @oddRowBGC;
      }
      .cell {
        display: inline-block;
        height: 100%;
        padding: 5px 5px;
        line-height: 1.2;
        vertical-align: middle;
      }
      &.finish {
        text-align: center;
        font-size: 14px;
        line-height: 40px;
        opacity: 0.8;
      }
    }
  }

  .m-auto-scroll-table__box {
    position: absolute;
    top: 35px;
    left: 0;
    right: 0;
    bottom: 0;
  }

  .m-auto-scroll-table__box>div {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    font-size: 14px;
  }

  .m-auto-scroll-table__box>div.no-data {
    // color: #35a3b6;
    color: @fontColor;
  }
}

</style>
